using System;
using System.Collections;
using System.Collections.Generic;
using System.Data.Linq;
using System.Linq;
using System.Linq.Expressions;

namespace RomanJendrusz.Amazon.ETL.Infrastructure.DataBase
{
    public class DerivedTableQuerySource<DervideEntity, BaseEntity>: IQuerySource<DervideEntity> where DervideEntity:BaseEntity  where BaseEntity:class 
    {
        private readonly Table<BaseEntity> table;
        private readonly IQueryable<BaseEntity> queryable;

        public DerivedTableQuerySource(Table<BaseEntity> table)
        {
            this.table = table;
            queryable = table;
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return ((IEnumerable<DervideEntity>) this).GetEnumerator();
        }

        public IEnumerator<DervideEntity> GetEnumerator()
        {
            return table.OfType<DervideEntity>().GetEnumerator();
        }

        public Expression Expression
        {
            get { return queryable.OfType<DervideEntity>().Expression; }
        }

        public Type ElementType
        {
            get { return queryable.OfType<DervideEntity>().ElementType; }
        }

        public IQueryProvider Provider
        {
            get { return queryable.Provider; }
        }

        public void Add(DervideEntity item)
        {
            if (table.GetOriginalEntityState(item) == null)
            {
                table.InsertOnSubmit(item);
            }
        }

        public void Attach(DervideEntity item)
        {
            table.Attach(item);
        }

        public void Remove(DervideEntity item)
        {
            table.DeleteOnSubmit(item);
        }

        public void RemoveAll(IEnumerable<DervideEntity> items)
        {
            table.DeleteAllOnSubmit(items);
        }

        #region IQuerySource<DervideEntity> Members


        public void AddAll(IEnumerable<DervideEntity> items)
        {
            foreach (var item in items)
            {
                Add(item);
            }
        }

        #endregion
    }
}